### Eclipse Workspace Patch 1.0
#P josm
Index: src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 931)
+++ src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(working copy)
@@ -1,8 +1,8 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
 package org.openstreetmap.josm.gui.dialogs;
 
+import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.marktr;
 
 import java.awt.BorderLayout;
 import java.awt.GridLayout;
@@ -11,13 +11,14 @@
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedList;
 
 import javax.swing.DefaultListModel;
 import javax.swing.JList;
+import javax.swing.JMenuItem;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.ListSelectionModel;
 
@@ -25,6 +26,7 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
 import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
 import org.openstreetmap.josm.gui.SideButton;
 
@@ -37,81 +39,139 @@
  */
 public class SelectionListDialog extends ToggleDialog implements SelectionChangedListener {
 
-	/**
-	 * The selection's list data.
-	 */
-	private final DefaultListModel list = new DefaultListModel();
-	/**
-	 * The display list.
-	 */
-	private JList displaylist = new JList(list);
+    private static final double ZOOMTO_MIN_SCALE = 0.00001;
 
-	public SelectionListDialog() {
-		super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
-		displaylist.setCellRenderer(new OsmPrimitivRenderer());
-		displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		displaylist.addMouseListener(new MouseAdapter(){
-			@Override public void mouseClicked(MouseEvent e) {
-				if (e.getClickCount() < 2)
-					return;
-				updateMap();
-			}
-		});
+    /**
+     * The selection's list data.
+     */
+    private final DefaultListModel list = new DefaultListModel();
+    /**
+     * The display list.
+     */
+    private JList displaylist = new JList(list);
 
-		add(new JScrollPane(displaylist), BorderLayout.CENTER);
+    public SelectionListDialog() {
+        super(tr("Current Selection"), "selectionlist", tr("Open a selection list window."), KeyEvent.VK_T, 150);
 
-		JPanel buttonPanel = new JPanel(new GridLayout(1,2));
+        final JPopupMenu popupMenu = new JPopupMenu();
+        displaylist.setCellRenderer(new OsmPrimitivRenderer());
+        displaylist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+        displaylist.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
+                    updateMap();
+            }
 
-		buttonPanel.add(new SideButton(marktr("Select"), "select", "SelectionList",
-		tr("Set the selected elements on the map to the selected items in the list above."), new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				updateMap();
-			}
-		}));
+            @Override
+            public void mousePressed(MouseEvent e) {
+                if (e.isPopupTrigger())
+                    popupMenu.show(e.getComponent(), e.getX(), e.getY());
+            }
 
-		buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."), new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				selectionChanged(Main.ds.getSelected());
+            @Override
+            public void mouseReleased(MouseEvent e) {
+                if (e.isPopupTrigger())
+                    popupMenu.show(e.getComponent(), e.getX(), e.getY());
             }
-		}));
 
-		buttonPanel.add(new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."), Main.main.menu.search));
+        });
 
-		add(buttonPanel, BorderLayout.SOUTH);
-		selectionChanged(Main.ds.getSelected());
+        add(new JScrollPane(displaylist), BorderLayout.CENTER);
 
-		DataSet.selListeners.add(this);
-	}
+        JPanel buttonPanel = new JPanel(new GridLayout(1, 2));
 
-	@Override public void setVisible(boolean b) {
-		super.setVisible(b);
-		if (b)
-			selectionChanged(Main.ds.getSelected());
-	}
+        buttonPanel.add(new SideButton(marktr("Select"), "select", "SelectionList",
+                tr("Set the selected elements on the map to the selected items in the list above."),
+                new ActionListener() {
+                    public void actionPerformed(ActionEvent e) {
+                        updateMap();
+                    }
+                }));
 
+        buttonPanel.add(new SideButton(marktr("Reload"), "refresh", "SelectionList", tr("Refresh the selection list."),
+                new ActionListener() {
+                    public void actionPerformed(ActionEvent e) {
+                        selectionChanged(Main.ds.getSelected());
+                    }
+                }));
 
-	/**
-	 * Called when the selection in the dataset changed.
-	 * @param newSelection The new selection array.
-	 */
-	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-		if (list == null || !isVisible())
-			return; // selection changed may be received in base class constructor before init
-		OsmPrimitive selArr[] = Main.ds.sort(newSelection);
-		list.setSize(selArr.length);
-		int i = 0;
-		for (OsmPrimitive osm : selArr)
-			list.setElementAt(osm, i++);
-	}
+        buttonPanel.add(new SideButton(marktr("Search"), "search", "SelectionList", tr("Search for objects."),
+                Main.main.menu.search));
 
-	/**
-	 * Sets the selection of the map to the current selected items.
-	 */
-	public void updateMap() {
-		Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
-		for (int i = 0; i < list.getSize(); ++i)
-			if (displaylist.isSelectedIndex(i))
-				sel.add((OsmPrimitive)list.get(i));
-		Main.ds.setSelected(sel);
-	}
+        add(buttonPanel, BorderLayout.SOUTH);
+
+        JMenuItem zoomTo = new JMenuItem("Zoom to selection");
+        zoomTo.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                zoomToSelection();
+            }
+        });
+        popupMenu.add(zoomTo);
+
+        selectionChanged(Main.ds.getSelected());
+
+        DataSet.selListeners.add(this);
+    }
+
+    @Override
+    public void setVisible(boolean b) {
+        super.setVisible(b);
+        if (b)
+            selectionChanged(Main.ds.getSelected());
+    }
+
+    public void zoomToSelection() {
+        BoundingXYVisitor box = new BoundingXYVisitor();
+        int[] selected = displaylist.getSelectedIndices();
+        if (selected.length > 0) {
+            // One or more elements are selected in the list -> we zoom only to them 
+            for (int i = 0; i < selected.length; i++) {
+                Object o = list.get(selected[i]);
+                if (o instanceof OsmPrimitive)
+                    ((OsmPrimitive) o).visit(box);
+            }
+        } else {
+            // No element is selected in the list -> we zoom to the whole selection  
+            for (int i = 0; i < list.getSize(); i++) {
+                Object o = list.get(i);
+                if (o instanceof OsmPrimitive)
+                    ((OsmPrimitive) o).visit(box);
+            }
+        }
+        if (box.max == null || box.min == null)
+            return;
+        if (box.max.equals(box.min))
+            Main.map.mapView.zoomTo(box.max, ZOOMTO_MIN_SCALE);
+        else {
+            Main.map.mapView.recalculateCenterScale(box);
+            if (Main.map.mapView.getScale() < ZOOMTO_MIN_SCALE)
+                Main.map.mapView.zoomTo(Main.map.mapView.getCenter(), ZOOMTO_MIN_SCALE);
+        }
+    }
+
+    /**
+     * Called when the selection in the dataset changed.
+     * @param newSelection The new selection array.
+     */
+    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+        if (list == null || !isVisible())
+            return; // selection changed may be received in base class constructor before init
+        OsmPrimitive selArr[] = DataSet.sort(newSelection);
+        list.setSize(selArr.length);
+        int i = 0;
+        for (OsmPrimitive osm : selArr)
+            list.setElementAt(osm, i++);
+    }
+
+    /**
+     * Sets the selection of the map to the current selected items.
+     */
+    public void updateMap() {
+        Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
+        for (int i = 0; i < list.getSize(); ++i)
+            if (displaylist.isSelectedIndex(i))
+                sel.add((OsmPrimitive) list.get(i));
+        Main.ds.setSelected(sel);
+    }
 }
